package com.lyf.network.learn.nio;

import org.junit.Test;

import java.io.*;
import java.lang.annotation.Documented;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.channels.Channel;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.concurrent.TimeUnit;

/**
 * @AUTHOR LYF
 * @DATE 2022/6/9
 * @VERSION 1.0
 * @DESC
 *
 * 主要的Channel:
 * FileChannel,ByteChannel
 * SocketChannel
 *
 * → 提升效率---有buffer和的
 *
 * ----____________________ -__-----------------
 * |   node  channel → buffer  → selector   node |
 * | __________________________-----------------
 *
 * **&*! -∑
 *
 * （1）Channel的获取、对文件进行读写操作--- Buffer
 * （2）Channel间的 数据通信
 *
 */
public class ChannelTest {
    private String path = "E:\\JavaProjects\\LearnProjects\\learn-practice\\java-base\\src\\main\\java\\com\\lyf\\network\\learn\\nio\\files\\tmp";
    /*
     *实现数据的输出
     */
    @Test
    public void test1(){
        FileInputStream inputStream = null;
        FileChannel fileChannel =null;
        try {
            inputStream = new FileInputStream(path);
            fileChannel = inputStream.getChannel();
            ByteBuffer buffer = ByteBuffer.allocate(10);
//              bb.flip();
//            if (n > 0)
//                dst.put(bb);
            int readN;
            while ((readN = fileChannel.read(buffer))!=-1){ // read →  从 channel读到 buffer
                System.out.println("读取了:"+readN);
                buffer.flip();
//                buf.put(magic);    // Prepend header
//                in.read(buf);      // Read data into rest of buffer
//                buf.flip();        // Flip buffer
//                out.write(buf);    // Write header + data to channel
                while(buffer.hasRemaining()){
                    System.out.println((char) buffer.get());
                }
                buffer.clear();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(fileChannel!=null&&!fileChannel.isOpen()) {
                try {
                    fileChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(inputStream!=null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 实现通道间的数据传输
     */
    @Test
    public void test2(){
        RandomAccessFile toFile = null;//"";
        RandomAccessFile fromFile = null;//"";

        try {
//            FileInputStream transforFromFileInputStream = new FileInputStream("E:\\JavaProjects\\LearnProjects\\learn-practice\\java-base\\src\\main\\java\\com\\lyf\\network\\learn\\nio\\files\\transforFrom");
//            FileInputStream transforToFileInputStream = new FileInputStream("E:\\JavaProjects\\LearnProjects\\learn-practice\\java-base\\src\\main\\java\\com\\lyf\\network\\learn\\nio\\files\\transforTo");
//            Channel channelTo = transforToFileInputStream.getChannel();
//            Channel channelFrom = transforFromFileInputStream.getChannel();
            //new RandomAccessFile().getChannel().transferFrom()

            toFile = new RandomAccessFile
                    ("E:\\JavaProjects\\LearnProjects\\learn-practice\\java-base\\src\\main\\java\\com\\lyf\\network\\learn\\nio\\files\\transforTo","rw");
            fromFile = new RandomAccessFile
                    ("E:\\JavaProjects\\LearnProjects\\learn-practice\\java-base\\src\\main\\java\\com\\lyf\\network\\learn\\nio\\files\\transforFrom","rw");


            FileChannel toChannel = toFile.getChannel();
            FileChannel fromChannel = fromFile.getChannel();

            fromChannel.transferTo(10,fromChannel.size(),toChannel);

            System.out.println("over...");

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * SocketChannel - ServerSocketChannel listening
     *
     * <p>Test: browser visit it </p>
     *
     * <h>hello</h>
     *
     *
     */
    @Test
    public void test3(){
       int port = 8888;
        try {
            ByteBuffer buffer = ByteBuffer.allocate(10);

            // 创建channel对象
            ServerSocketChannel socketChannel = ServerSocketChannel.open();
            socketChannel.socket().bind(new InetSocketAddress(port));
            //配置阻模式
            socketChannel.configureBlocking(false);
            while (true){

                System.out.println("waiting...");
                SocketChannel socketChannel1 = socketChannel.accept();
                if(socketChannel1==null){
                    System.out.println("no req...");
                    Thread.sleep(2000);
                }else{
                    System.out.println(socketChannel1+":::");
                    buffer.rewind();//置空
                    socketChannel1.write(buffer);
                    buffer.flip();
                    System.out.println(buffer);

                    //
                    Buffer bb = ByteBuffer.wrap("hello".getBytes());
                    socketChannel1.read((ByteBuffer) bb);

                }

            }

        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


    }
    @Test
    public void test4() throws Exception{
        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.connect(new InetSocketAddress("",8888));
        socketChannel.configureBlocking(false);

        while (true){

            //socketChannel.write()

            TimeUnit.SECONDS.sleep(1);
        }

    }


}
